package com.zmn.oms.dubbo.impl.zmn.normal.warranty;

import org.apache.dubbo.config.annotation.Service;
import com.google.common.collect.Lists;
import com.jd.open.api.sdk.internal.JSON.JSON;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.dubbo.dto.zmn.warranty.OrderWarrantyListDRO;
import com.zmn.oms.dubbo.dto.zmn.warranty.WarrantyListUserDRO;
import com.zmn.oms.dubbo.dto.zmn.warranty.WarrantyUserDRO;
import com.zmn.oms.dubbo.interfaces.zmn.normal.warranty.ZsNormalOrderWarrantyRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.model.entity.comment.OrderComment;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.warranty.WarrantyListOrderVO;
import com.zmn.oms.model.vo.warranty.WarrantyListUserVO;
import com.zmn.oms.model.vo.warranty.WarrantyProductUserVO;
import com.zmn.oms.model.vo.warranty.WarrantyUserVO;
import com.zmn.oms.services.interfaces.comment.OrderCommentService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.normal.business.interfaces.warranty.ZsNormalOrderWarrantyBService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.net.URLDecoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述： 保单 remote service
 *
 * @author yule
 * @date 2020/7/30 16:46
 */
@Service(loadbalance = "roundrobin", timeout = 5000, retries = 2, version = DubboConsts.INTERFACE_VERSION, validation = "false")
public class ZsNormalOrderWarrantyRemoteServiceImpl implements ZsNormalOrderWarrantyRemoteService {

    private Logger logger = LoggerFactory.getLogger(ZsNormalOrderWarrantyRemoteServiceImpl.class);

    private static final String TAG = "啄木鸟-普通工单-保修卡dubbo接口";

    @Autowired
    private ZsNormalOrderWarrantyBService zsNormalOrderWarrantyBService;
    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OrderCommentService orderCommentService;

    /**
     * 获取保修卡
     *
     * @param orderId
     * @return
     */
    @Override
    public ResponseDTO<WarrantyUserDRO> findWarrantyByOrderId(Long orderId) {
        if (orderId == null) {
            return ResponseDTO.fail("orderId 不为空");
        }

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        if (orderWork == null) {
            return ResponseDTO.fail("订单不存在");
        }

        Integer status = orderWork.getStatus();
        if (status < OrderStatusConsts.WORK_STATUS_COMPLETE) {
            return ResponseDTO.fail("订单未完成");
        }

        WarrantyUserVO warrantyVO = zsNormalOrderWarrantyBService.findWarrantyByOrderId(orderId);
        if (warrantyVO == null) {
            return ResponseDTO.fail("无保修信息");
        }

        if (CollectionUtils.isEmpty(warrantyVO.getWarrantyProductList())) {
            return ResponseDTO.fail("获取保修信息失败");
        }

        WarrantyUserDRO userDRO = BeanMapper.map(warrantyVO, WarrantyUserDRO.class);

        // region 处理其他数据 此处 处理不属于保修接口范畴 ，但是调用者需要使用该参数
        handleOtherDROParam(warrantyVO, userDRO, orderId);
        // endRegion

        return ResponseDTO.success(userDRO, GlobalConsts.SUCCESS_MSG);
    }

    /**
     * 获取保修卡（不校验工单状态）
     * sass服务验收接口使用，完成前要展示保修信息
     * @param orderId
     * @return
     */
    @Override
    public ResponseDTO<WarrantyUserDRO> findAllWarrantyByOrderId(Long orderId) {
        if (orderId == null) {
            return ResponseDTO.fail("orderId 不为空");
        }

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        if (orderWork == null) {
            return ResponseDTO.fail("订单不存在");
        }

        WarrantyUserVO warrantyVO = zsNormalOrderWarrantyBService.findWarrantyByOrderId(orderId);
        if (warrantyVO == null) {
            return ResponseDTO.fail("无保修信息");
        }

        if (CollectionUtils.isEmpty(warrantyVO.getWarrantyProductList())) {
            return ResponseDTO.fail("获取保修信息失败");
        }

        // 如果保修卡生效时间为空，则使用当前时间
        warrantyVO.setEffectiveTime(Optional.ofNullable(warrantyVO.getEffectiveTime()).orElse(DateUtil.getNow()));
        warrantyVO.getWarrantyProductList().forEach(product -> {
            if (Objects.isNull(product.getExpiredTime())) {
                product.setExpiredTime(DateUtil.addDays(warrantyVO.getEffectiveTime(), product.getDay()));
            }
        });

        WarrantyUserDRO userDRO = BeanMapper.map(warrantyVO, WarrantyUserDRO.class);

        // region 处理其他数据 此处 处理不属于保修接口范畴 ，但是调用者需要使用该参数
        handleOtherDROParam(warrantyVO, userDRO, orderId);
        // endRegion

        return ResponseDTO.success(userDRO, GlobalConsts.SUCCESS_MSG);
    }

    @Override
    public ResponseDTO<List<OrderWarrantyListDRO>> listWarrantyByOrderIds(Set<Long> orderIds) {
        if (CollectionUtils.isEmpty(orderIds)) {
            return ResponseDTO.fail("参数不能为空");
        }
        List<Long> orderList = Lists.newArrayList(orderIds);
        List<Long> orderListSub;
        if (orderIds.size() > 100) {
            orderListSub = orderList.subList(0, 99);
        } else {
            orderListSub = orderList;
        }
        List<WarrantyListOrderVO> list = zsNormalOrderWarrantyBService.listWarrantyByOrderIdList(orderListSub);

        List<OrderWarrantyListDRO> warrantyListDRO = BeanMapper.mapList(list, OrderWarrantyListDRO.class);

        return ResponseDTO.success(warrantyListDRO, GlobalConsts.SUCCESS_MSG);
    }

    /**
     * 获取保修卡详情
     *
     * @param orderId 订单号
     * @param codeStr 保修卡号
     * @return
     */
    @Override
    public ResponseDTO<WarrantyUserDRO> findWarrantyDetailByOrderIdAndCode(Long orderId, String codeStr) {
        logger.info("orderId={},code={}保修卡查询入参", orderId, codeStr);
        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        if (Objects.isNull(dbOrderWork)) {
            return ResponseDTO.fail("订单不存在");
        }

        if (dbOrderWork.getStatus() < OrderStatusConsts.WORK_STATUS_COMPLETE) {
            return ResponseDTO.fail("订单未完成");
        }

        String code = codeStr;
        if (codeStr.contains("%2")) {
            try {
                code = URLDecoder.decode(codeStr, GlobalConsts.UTF8_ENCODING);
            } catch (Exception e) {
                logger.error("[{}] 保修卡解码失败：{}", TAG, e);
                return ResponseDTO.fail(e.getMessage());
            }
        }

        WarrantyUserVO warrantyVO = zsNormalOrderWarrantyBService.findWarrantyDetailByOrderIdAndCode(orderId, code);
        if (warrantyVO == null) {
            return ResponseDTO.fail();
        }

        if (CollectionUtils.isEmpty(warrantyVO.getWarrantyProductList())) {
            return ResponseDTO.fail("获取保修信息失败");
        }

        WarrantyUserDRO userDRO = BeanMapper.map(warrantyVO, WarrantyUserDRO.class);

        // region 处理其他数据 此处 处理不属于保修接口范畴 ，但是调用者需要使用该参数
        handleOtherDROParam(warrantyVO, userDRO, orderId);
        // endRegion

        return ResponseDTO.success(userDRO, GlobalConsts.SUCCESS_MSG);
    }

    /**
     * 处理保修接口非保修的其他参数
     * @param warrantyVO
     * @param userDRO
     * @param orderId
     */
    private void handleOtherDROParam(WarrantyUserVO warrantyVO, WarrantyUserDRO userDRO, Long orderId) {
        // 处理评价
        OrderComment orderComment = orderCommentService.findCommentByKey(orderId);
        if (orderComment == null || Objects.equals(orderComment.getStatus(), GlobalConsts.NO)) {
            userDRO.setComment(true);
        } else {
            userDRO.setComment(false);
        }

        // 处理返修 及 处理有效性
        Optional<WarrantyProductUserVO> max = warrantyVO.getWarrantyProductList().stream().max(Comparator.comparing(WarrantyProductUserVO::getExpiredTime));

        if (Objects.equals(OrderConsts.ORDER_WARRANTY_TYPE_CARD, warrantyVO.getType())) {
            if (max.isPresent()) {
                Date expiredTime = max.get().getExpiredTime();
                if (expiredTime.after(DateUtil.getNow())) {
                    userDRO.setEffectived(true);
                    userDRO.setRepair(true);
                } else {
                    userDRO.setEffectived(false);
                }
            }
        } else {
            userDRO.setEffectived(true);
        }
    }


    /**
     * 保修卡
     *
     * @param userId
     * @return
     */
    @Override
    public ResponseDTO<List<WarrantyListUserDRO>> listWarrantyByUserId(Long userId) {
        logger.info("用户查询保修卡列表入参userId={}", userId);
        List<WarrantyListUserVO> warranties = zsNormalOrderWarrantyBService.listWarrantyByUserId(userId);
        logger.info("保修卡查询结果[{}]", warranties);
        // 列表转换
        List<WarrantyListUserDRO> warrantyDROS = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(warranties)) {
            warrantyDROS = BeanMapper.mapList(warranties, WarrantyListUserDRO.class);

            warrantyDROS.stream().sorted(Comparator.comparing(WarrantyListUserDRO::getCreateTime,
                    Comparator.nullsLast(Date::compareTo)).reversed()).collect(Collectors.toList());
        }
        return ResponseDTO.success(warrantyDROS, "OK");
    }

    /**
     * 多用户查询保修卡列表
     *
     * @param userIdList
     * @return
     */
    @Override
    public ResponseDTO<List<WarrantyListUserDRO>> listWarrantyByUserIds(Set<Long> userIdList) {
        logger.info("多用户查询保修卡列表入参{}", JSON.toString(userIdList));
        // 注：因为改动比较大，接口实现临时处理
        // 需要和上面#ZsNormalOrderWarrantyRemoteServiceImpl.listWarrantyByUserId接口整合
        if (userIdList.isEmpty()) {
            return ResponseDTO.fail("用户信息不能为空");
        }

        List<WarrantyListUserDRO> warrantyDRO = Lists.newArrayList();

        for (Long userId : userIdList) {
            List<WarrantyListUserVO> warranties = zsNormalOrderWarrantyBService.listWarrantyByUserId(userId);
            if (CollectionUtil.isNullOrEmpty(warranties)) {
                continue;
            }
            List<WarrantyListUserDRO> warrantyDROS = BeanMapper.mapList(warranties, WarrantyListUserDRO.class);
            warrantyDRO.addAll(warrantyDROS);
        }

        if (CollectionUtil.isNullOrEmpty(warrantyDRO)) {
            return ResponseDTO.success();
        }

        // 去重
        List<WarrantyListUserDRO> filterWarrantys = warrantyDRO.stream().collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WarrantyListUserDRO::getCode)))
                        , ArrayList::new)
        );

        // 排序
        List<WarrantyListUserDRO> sortWarrantys = filterWarrantys.stream().sorted(Comparator.comparing(WarrantyListUserDRO::getCreateTime,
                Comparator.nullsLast(Date::compareTo)).reversed()).collect(Collectors.toList());

        return ResponseDTO.success(sortWarrantys, "OK");
    }

    /**
     * 激活保单
     *
     * @param orderId 用户id
     * @return 激活结果
     */
    @Override
    public ResponseDTO activeWarranty(Long orderId) {
        zsNormalOrderWarrantyBService.activeWarranty(orderId);
        return ResponseDTO.success(null, "OK");
    }

    /**
     * 领取保修卡
     *
     * @param orderId
     * @param userId
     * @return
     */
    @Override
    public ResponseDTO takeWarranty(Long orderId, Long userId) {
        zsNormalOrderWarrantyBService.takeWarranty(orderId, userId);
        return ResponseDTO.success(null, "OK");
    }
}
